<?php
declare (strict_types = 1);

namespace app\common;

use think\facade\Cache;
use think\facade\Log;
use think\facade\Db;
use think\queue\Job;

class Queue
{
    protected static $queueName = 'default';
    
    /**
     * 推送任务到队列
     * @param string $type 任务类型
     * @param array $data 任务数据
     * @return bool
     */
    public static function push($type, $data = [])
    {
        try {
            $job = [
                'type' => $type,
                'data' => $data,
                'created_at' => time()
            ];
            
            Cache::store('redis')->lpush(self::$queueName, json_encode($job));
            return true;
            
        } catch (\Exception $e) {
            Log::error('Queue push error: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * 推送通知任务
     */
    public static function pushNotification($userId, $message, $type = 'system')
    {
        return self::push('send_notification', [
            'user_id' => $userId,
            'message' => $message,
            'type' => $type
        ]);
    }

    /**
     * 队列任务处理入口
     * @param Job $job    队列任务实例
     * @param array $data 投递的数据
     */
    public function fire(Job $job, $data)
    {
        try {
            // 1. 记录任务开始
            $this->logMessage("开始处理任务: " . json_encode($data));
            
            // 2. 执行具体任务
            $this->handleJob($data);
            
            // 3. 任务执行成功，删除任务
            $job->delete();
            
        } catch (\Exception $e) {
            // 4. 任务失败处理
            if ($job->attempts() > 3) {
                // 重试超过3次，放弃任务
                $job->delete();
            } else {
                // 重试任务
                $job->release(3); // 延迟3秒后重试
            }
        }
    }
    
    /**
     * 处理具体任务
     * @param array $data
     */
    protected function handleJob($data)
    {
        // 根据任务类型分发处理
        switch ($data['type']) {
            case 'create_user':
                $this->handleCreateUser($data['data']);
                break;
                
            case 'send_notification':
                $this->handleNotification($data['data']);
                break;
                
            default:
                throw new \Exception("Unknown job type: {$data['type']}");
        }
    }

    /**
     * 处理创建用户任务
     * @param array $data
     */
    protected function handleCreateUser($data)
    {
        try {
            $userData = $data['user_data'];
            
            // 验证必要字段
            if (empty($userData['username']) || empty($userData['password'])) {
                throw new \Exception('Missing required user data');
            }

            // 检查用户是否已存在
            $exists = Db::name('user')->where('username', $userData['username'])->find();
            if ($exists) {
                throw new \Exception('Username already exists');
            }

            // 处理密码
            $userData['password'] = password_hash($userData['password'], PASSWORD_DEFAULT);
            
            // 添加创建时间
            $userData['create_time'] = time();
            $userData['update_time'] = time();

            // 创建用户
            $userId = Db::name('user')->insertGetId($userData);
            
            // 记录日志
            $this->logMessage("User created successfully: ID = {$userId}");

            // 可以在这里添加其他初始化操作
            // 例如：创建用户钱包、初始化用户配置等
            
            return $userId;
            
        } catch (\Exception $e) {
            $this->logMessage("Create user failed: " . $e->getMessage());
            throw $e; // 重新抛出异常，让队列知道任务失败了
        }
    }

    /**
     * 处理具体任务
     * @param array $data
     */
    protected function handleNotification($data)
    {
        // 实现处理通知任务的逻辑
    }

    /**
     * 处理具体任务
     * @param array $data
     */
    protected function handlePlayerStats($data)
    {
        // 实现处理玩家统计任务的逻辑
    }

    /**
     * 处理具体任务
     * @param array $data
     */
    protected function handleRoomCleanup($data)
    {
        // 实现处理房间清理任务的逻辑
    }
    
    protected function logMessage($message)
    {
        $log = "[" . date('Y-m-d H:i:s') . "] " . $message . "\n";
        file_put_contents(runtime_path() . 'queue.log', $log, FILE_APPEND);
    }
} 